﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DeploymentMaxLib
{
    public static class Extensions
    {
        public static string ReadAllText(this System.IO.StreamReader pStreamReader)
        {
            var sb = new StringBuilder();

            while (!pStreamReader.EndOfStream)
            {
                var str = pStreamReader.ReadLine().Trim();
                if (str.Length != 0)
                {
                    sb.AppendLine(str);
                }
            }

            return sb.ToString();
        }

        private static readonly System.Text.RegularExpressions.Regex mRegexGuid =

            new System.Text.RegularExpressions.Regex(@"^((\A\([a-f\d]{8}(-[a-f\d]{4}){3}-[a-f\d]{12}\)\z)|(\A\{[a-f\d]{8}(-[a-f\d]{4}){3}-[a-f\d]{12}\}\z)|(\A\{\s*0x[a-f\d]{8}\s*,\s*(0x[a-f\d]{4}\s*,\s*){2}\{\s*(0x[a-f\d]{2}\s*,\s*){7}0x[a-f\d]{2}\s*\}\s*}\z)|(\A[a-f\d]{32}\z))$",
                  System.Text.RegularExpressions.RegexOptions.Compiled |
                  System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace |
                   System.Text.RegularExpressions.RegexOptions.IgnoreCase
              );

        public static bool IsGuid(this string g)
        {
            return !string.IsNullOrEmpty(g) || mRegexGuid.IsMatch(g);
        }

        public static double? DoubleValueOrNull(this string pValue, int decimals)
        {
            double? t = pValue.DoubleValueOrNull();
            if (t != null)
            {
                t = Math.Round(t.Value, decimals);
            }
            return t;
        }

        public static string Left(this string pValue, int pMaxLength)
        {
            if (pValue == null) return "";
            if (pValue.Length > pMaxLength)
            {
                pValue = pValue.Substring(0, pMaxLength);
            }
            return pValue;
        }

        public static string LeftOrNull(this string pValue, int pMaxLength)
        {
            if (pValue == null) return null;
            if (pValue.Length > pMaxLength)
            {
                pValue = pValue.Substring(0, pMaxLength);
            }
            return pValue;
        }

        public static string Right(this string pValue, int pMaxLength)
        {
            if (pValue == null) return "";
            if (pValue.Length > pMaxLength)
            {
                pValue = pValue.Substring(pValue.Length - pMaxLength);
            }
            return pValue;
        }

        public static string RightOrNull(this string pValue, int pMaxLength)
        {
            if (pValue == null) return null;
            if (pValue.Length > pMaxLength)
            {
                pValue = pValue.Substring(pValue.Length - pMaxLength);
            }
            return pValue;
        }

        public static string SQLDateTimeDBValue(this string pValue)
        {
            string tResult = " NULL ";
            if (!pValue.IsEmpty())
            {
                object tValue = pValue.SqlDateTimeSringOrDBNull();
                if (tValue != DBNull.Value)
                {
                    tResult = "'" + tValue.ToString() + "'";
                }
            }
            return tResult;
        }

        public static object SqlDateTimeSringOrDBNull(this string pValue)
        {
            try
            {
                return System.Data.SqlTypes.SqlDateTime.Parse(pValue).ToString();
            }
            catch
            {
                return DBNull.Value;
            }
        }

        public static DateTime? SqlDateTimeOrNull(this object pValue)
        {
            DateTime? tResult = null;

            if (pValue is DateTime || pValue is DateTime?)
            {
                if (pValue != null)
                    tResult = (DateTime)pValue;
            }
            else
            {
                if (!pValue.IsEmpty())
                    tResult = pValue.ToString().DateValueOrNull();
            }

            if (tResult != null && (tResult.Value < DateTime.Parse("1/1/1753 12:00:00 AM") ||
                tResult.Value > DateTime.Parse("12/31/9999 11:59:59 PM")))
            {
                tResult = null;
            }

            return tResult;

        }

        public static System.DateTime? DateValueOrNull(this string pValue)
        {
            System.DateTime tVal;
            if (System.DateTime.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return null;
            }

        }

        public static DateTime? StripSecondsAndMilliseconds(this DateTime? pDateTime)
        {
            if (pDateTime == null)
            {
                return null;
            }
            else
            {
                return pDateTime.Value.StripSecondsAndMilliseconds();
            }
        }

        public static DateTime StripSecondsAndMilliseconds(this DateTime pDateTime)
        {
            return pDateTime.Date.AddHours(pDateTime.Hour).AddMinutes(pDateTime.Minute);// .AddSeconds(-pDateTime.Second).AddMilliseconds(-pDateTime.Millisecond);
        }

        public static System.DateTime ReplaceTimeValue(this DateTime pDateValue, DateTime pTimeValue)
        {
            return pDateValue.Date + pTimeValue.TimeOfDay;
        }

        public static System.DateTime? ReplaceTimeValueOrNull(this string pDateValue, string pTimeValue)
        {
            return pDateValue.DateValueOrNull().ReplaceTimeValueOrNull(pTimeValue.DateValueOrNull());
        }

        public static System.DateTime? ReplaceTimeValueOrNull(this DateTime? pDateValue, DateTime? pTimeValue)
        {
            if (pDateValue.HasValue && pTimeValue.HasValue)
            {
                return pDateValue.Value.Date + pTimeValue.Value.TimeOfDay;
            }
            else
            {
                return null;
            }

        }

        public static System.DateTime DateValueOrMin(this string pValue)
        {
            System.DateTime tVal;
            if (System.DateTime.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return DateTime.MinValue;
            }

        }

        public static long? LongValueOrNull(this string pValue)
        {
            long tVal;
            if (long.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return null;
            }

        }

        public static bool BoolValue(this object pValue)
        {
            return pValue.StringValueOrEmpty().BoolValue();

        }

        public static bool BoolValue(this string pValue)
        {
            if (pValue == null || pValue == string.Empty || pValue.Trim().Length == 0) { return false; }
            bool tOut = false;
            if (bool.TryParse(pValue, out tOut))
            {
                return tOut;
            }
            else
            {
                if (pValue.ToUpper() == "Y" || pValue.ToUpper() == "YES" || pValue.ToUpper() == "1" || pValue.ToUpper() == "-1" || pValue.ToUpper() == "T" || pValue.ToUpper() == "TRUE")
                    return true;
                else if (pValue.ToUpper() == "N" || pValue.ToUpper() == "NO" || pValue.ToUpper() == "0" || pValue.ToUpper() == "F" || pValue.ToUpper() == "FALSE")
                    return false;
                else
                    throw new Exception("Invalid value for boolean type: " + pValue + ".");
            }

        }

        public static bool? BoolValueOrNull(this string pValue)
        {
            bool tOut = false;
            if (bool.TryParse(pValue, out tOut))
            {
                return tOut;
            }
            else
            {
                if (pValue.ToUpper() == "Y" || pValue.ToUpper() == "YES" || pValue.ToUpper() == "1" || pValue.ToUpper() == "T" || pValue.ToUpper() == "TRUE")
                    return true;
                else if (pValue.ToUpper() == "N" || pValue.ToUpper() == "NO" || pValue.ToUpper() == "0" || pValue.ToUpper() == "F" || pValue.ToUpper() == "FALSE")
                    return false;
                else
                    return null;
            }

        }

        public static short? ShortValueOrNull(this string pValue)
        {
            short tVal;
            if (short.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return null;
            }

        }

        public static bool IsNumeric(this string pValue)
        {
            double tResult = 0;
            return double.TryParse(pValue, out tResult);
        }

        public static bool IsEmpty(this object pValue)
        {

            if (pValue == null || pValue.Equals(string.Empty) || DBNull.Value.Equals(pValue))
            {
                return true;
            }
            else
            {
                return pValue.ToString().Trim().Length == 0;
            }
        }

        public static bool HasValue(this object pValue)
        {

            return !IsEmpty(pValue);
        }

        public static int? IntValueOrNull(this string pValue)
        {
            int tVal;
            if (IsNumeric(pValue))
            {
                tVal = Convert.ToInt32(DecimalValueOrNull(pValue));
                return tVal;
            }
            else
            {
                return null;
            }
        }

        public static int IntValueOrZero(this string pValue)
        {
            int tVal;
            if (IsNumeric(pValue))
            {
                tVal = Convert.ToInt32(DecimalValueOrZero(pValue));
                return tVal;
            }
            else
            {
                return 0;
            }
        }

        public static int IntValueOrDefault(this string pValue, int pDefaultValue)
        {
            int tVal;
            if (int.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return pDefaultValue;
            }
        }

        public static double? DoubleValueOrNull(this string pValue)
        {
            double tVal;
            if (double.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return null;
            }

        }

        public static double DoubleValueOrZero(this string pValue)
        {
            double tVal;
            if (double.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return 0;
            }

        }

        public static decimal? DecimalValueOrNull(this string pValue)
        {
            decimal tVal;
            if (decimal.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return null;
            }

        }

        public static long LongValueOrZero(this string pValue)
        {
            long tVal;
            if (long.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return 0;
            }

        }

        public static decimal DecimalValueOrZero(this string pValue)
        {
            decimal tVal;
            if (decimal.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return 0;
            }

        }

        public static short ShortValueOrZero(this string pValue)
        {
            short tVal;
            if (short.TryParse(pValue, out tVal))
            {
                return tVal;
            }
            else
            {
                return 0;
            }

        }

        public static string StringValueOrEmpty(this object pValue)
        {
            if (pValue == null)
            {
                return "";
            }

            return pValue.ToString();
        }

        public static string StringValueOrEmpty(this object pValue, int pMaxLength)
        {
            if (pValue == null)
            {
                return "";
            }

            var t = pValue.ToString();
            if (t.Length > pMaxLength)
            {
                return t.Substring(0, pMaxLength);
            }
            else
            {
                return t;
            }
        }

        public static string GetValueOrDefault(this object pValue, string pDefault)
        {
            if (pValue == null)
            {
                return pDefault;
            }

            return pValue.ToString();
        }

        public static string DBString(this string pValue)
        {
            if (pValue.IsEmpty())
            {
                return " NULL ";
            }

            return "'" + pValue.Replace("'", "''") + "'";

        }

        public static string DBString(this string pValue, int pMaxLength)
        {
            if (IsEmpty(pValue))
            {
                return " NULL ";
            }
            else
            {
                if (pValue.Length > pMaxLength)
                {
                    return "'" + pValue.Substring(0, pMaxLength).Replace("'", "''") + "'";
                }
                else
                {
                    return "'" + pValue.Replace("'", "''") + "'";
                }

            }

        }

        public static string DBString(this DateTime pValue)
        {
            try
            {
                return "'" + System.Data.SqlTypes.SqlDateTime.Parse(pValue.ToString()).ToString() + "'";
            }
            catch
            {
                return " NULL ";
            }
        }

        public static string DBString(this DateTime? pValue)
        {
            if (pValue == null)
            {
                return " NULL ";
            }
            return pValue.Value.DBString();

        }

        public static string DBString(this double pValue)
        {
            return "'" + pValue.ToString() + "'";
        }

        public static string DBString(this int pValue)
        {
            return "'" + pValue.ToString() + "'";
        }

        public static string DBString(this double? pValue)
        {
            if (pValue == null)
            {
                return " NULL ";
            }

            return pValue.Value.DBString();
        }

        public static string DBString(this int? pValue)
        {
            if (pValue == null)
            {
                return " NULL ";
            }

            return pValue.Value.DBString();
        }

        public static string DBString(this bool? pValue)
        {
            if (pValue == null)
            {
                return " NULL ";
            }

            return pValue.Value.DBString();
        }

        public static string DBString(this bool pValue)
        {
            if (pValue)
            {
                return " '1' ";
            }

            return "'0'";
        }

        public static string StringValueOrEmpty(this double? pValue)
        {

            if (pValue == null)
            {
                return "";
            }
            else
            {
                return pValue.Value.ToString();
            }

        }

        public static string StringValueOrEmpty(this DateTime? pValue)
        {

            if (pValue == null)
            {
                return "";
            }
            else
            {
                return pValue.Value.ToString();
            }

        }

        public static string TruncateFromLeft(this string pValue, int pLength)
        {
            string tSubstring = "";
            if (pValue != null)
            {
                if (pValue.Length > pLength)
                {
                    tSubstring = pValue.Substring(0, pLength);
                }
            }
            return tSubstring;
        }

        public static T ToEnum<T>(this string pEnumString)
        {
            return (T)Enum.Parse(typeof(T), pEnumString);
        }

        public static void MakeWritable(this System.IO.FileInfo pFileInfo)
        {
            if ((pFileInfo.Attributes & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly)
            {
                pFileInfo.Attributes = (System.IO.FileAttributes)(((int)pFileInfo.Attributes) & (~(int)System.IO.FileAttributes.ReadOnly));
            }
        }

        public static void MakeWritable(this System.IO.DirectoryInfo pDirectoryInfo)
        {
            if ((pDirectoryInfo.Attributes & System.IO.FileAttributes.ReadOnly) == System.IO.FileAttributes.ReadOnly)
            {
                pDirectoryInfo.Attributes = (System.IO.FileAttributes)(((int)pDirectoryInfo.Attributes) & (~(int)System.IO.FileAttributes.ReadOnly));
            }
        }


    }
}
